/* Copyright (c) 2021, National University of Defense Technology. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "csr_transpose.h"

namespace YHAMG
{

void CSR_Transpose(const CSR_Matrix& A, CSR_Matrix& B)
{
	int n = A.size[0];
	int m = A.size[1];
	int* Ap = A.rowptr;
	int* Ai = A.colind;
	double* Av = A.values;

	int* Bp = new int[m + 1];
	int* Bi = new int[Ap[n]];
	double* Bv = new double[Ap[n]];

	for (int i = 0; i <= m; ++i)
		Bp[i] = 0;

	for (int j = Ap[0]; j < Ap[n]; ++j)
		++Bp[Ai[j]];

	for (int i = 0; i < m; ++i)
		Bp[i + 1] += Bp[i];

	for (int i = n - 1; i >= 0; --i)
	{
		for (int j = Ap[i + 1] - 1; j >= Ap[i]; --j)
		{
			Bi[--Bp[Ai[j]]] = i;
			Bv[Bp[Ai[j]]] = Av[j];
		}
	}

	B.Free();
	B.size[0] = m;
	B.size[1] = n;
	B.rowptr = Bp;
	B.colind = Bi;
	B.values = Bv;
}

}